#include "head.h"
#include <func.h>

int getCommand(char buf[], char command[]);
int main(int argc, char *argv[]){
    // ./client.c 192.168.31.128 1234
    ARGS_CHECK(argc, 3);
    int sockFd = socket(AF_INET, SOCK_STREAM, 0);  // 创建一个网络套接字
    struct sockaddr_in addr;
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_family = AF_INET;
    int ret = connect(sockFd, (struct sockaddr*)&addr, sizeof(addr));   // 发起第一次握手
    ERROR_CHECK(ret, -1, "connect");

    puts("Please input your username.");
    char username[50] = {0};
    char ch;
    int i = 0;
    //getchar();
    while((ch = getchar()) != '\n'){
        username[i++] = ch;
    }
    train_t usrname_train;
    bzero(&usrname_train, sizeof(train_t));
    usrname_train.dataLength = strlen(username);
    strcpy(usrname_train.buf, username);
    send(sockFd, &usrname_train, sizeof(usrname_train.dataLength)+usrname_train.dataLength, 0);

    int fd = open(username, O_RDWR);
    //客户端下存储与用户名同名文件，文件内容为用户存储的token值
    if(fd == -1){//文件不存在，说明该用户尚未注册/用户存在但未存储token
        send(sockFd, "0", 1, MSG_NOSIGNAL);//通知服务端为上述情况，让服务端进入对应分支
        //登录选项
        puts("Please input your choice: 1.Login 2.Register");
        char choice = getchar();
        if(choice != '1' && choice != '2'){
            puts("Wrong Choice!");
            exit(0);
        }
        else{
            send(sockFd, &choice, 1, MSG_NOSIGNAL);
        }

        //输入用户名和密码
        // char name[20] = {0};
        char passwd[20] = {0};
        // puts("Please input the usr_name.");
        // char ch;
        // int i = 0;
        // getchar();
        // while((ch = getchar()) != '\n'){
        //     name[i++] = ch;
        // }
        puts("Please input the password.");
        i = 0;
        getchar();
        while((ch = getchar()) != '\n'){
            passwd[i++] = ch;
        }
        //printf("passwd = %s\n", passwd);

        train_t t;
        //发送用户名和密码验证登录
        char sendMsg[1024] = {0};
        sprintf(t.buf, "%s %s", username, passwd);
        t.dataLength = strlen(t.buf);
        ret = send(sockFd, &t, sizeof(t.dataLength)+t.dataLength, 0);
        ERROR_CHECK(ret, -1, "send username and password");
        // char result[1024] = {0};
        // recv(sockFd, result, sizeof(result), 0);
        // puts(result);

        char serverBack;
        recv(sockFd, &serverBack, 1, 0);
        if(choice == '1'){//登录分支
            if(serverBack + '0' == '0'){
                puts("LOGIN");
            }
            else if(serverBack + '0' == '1'){
                puts("Wrong password.");
                exit(0);
            }
            else{
                puts("User doesn't exist.");
                exit(0);
            }
        }
        else if(choice == '2'){//注册分支
            if(serverBack == '0'){
                puts("Register Success!");
            }
            else{
                puts("Register Failed!");
                exit(0);
            }
        }
        //接收服务端发送来的token并存入文件
        int length;
        char token[100] = {0};
        recv(sockFd, &length, sizeof(int), 0);
        recv(sockFd, token, length, 0);
        int tokenFd = open(username, O_CREAT|O_RDWR, 0666);
        write(tokenFd, token, strlen(token));
        close(tokenFd);
    }
    else{//文件已存在，说明用户已注册，从中取出其token值
        //有三种可能
        //1.token过期--->服务端token为空
        //2.token不匹配--->非法用户
        //3.token匹配--->合法用户
        send(sockFd, "1", 1, MSG_NOSIGNAL);
        char token[50] = {0};
        read(fd, token, sizeof(token));
        train_t token_train;
        bzero(&token_train, sizeof(token_train));
        token_train.dataLength = strlen(token);
        strcpy(token_train.buf, token);
        int ret = send(sockFd, &token_train, sizeof(token_train.dataLength)+token_train.dataLength, MSG_NOSIGNAL);
        ERROR_CHECK(ret, -1, "send token");//向服务端发送当前token 
        //向服务端发送用户名
        train_t name_train;
        bzero(&name_train, sizeof(name_train));
        name_train.dataLength = strlen(username);
        strcpy(name_train.buf, username);
        ret = send(sockFd, &name_train, sizeof(name_train.dataLength) + name_train.dataLength, MSG_NOSIGNAL);
        ERROR_CHECK(ret, -1, "send name");
        //通过服务端数据库token是否为空进入不同分支
        char tokenSig;
        recv(sockFd, &tokenSig, 1, 0);
        if(tokenSig == '2'){
            puts("Wrong");
            exit(0);
        }
        else if(tokenSig == '0'){//token不为空，有匹配和不匹配两种情况
            recv(sockFd, &tokenSig, 1, 0);
            if(tokenSig == '1'){
                puts("Illegal user");
                exit(0);
            }
            else if(tokenSig == '0'){
                puts("Welcome");
            }
        }
        else if(tokenSig == '1'){//token为空，用户token过期，重新验证用户信息
            puts("Identity is overdue");
            puts("Please input the password.");
            i = 0;
            //getchar();//?
            char passwd[100] = {0};
            while((ch = getchar()) != '\n'){
                passwd[i++] = ch;
            }
            train_t t;
            //发送用户名和密码验证登录
            char sendMsg[1024] = {0};
            sprintf(t.buf, "%s %s", username, passwd);
            t.dataLength = strlen(t.buf);
            ret = send(sockFd, &t, sizeof(t.dataLength)+t.dataLength, 0);
            ERROR_CHECK(ret, -1, "send username and password");

            char serverBack;
            recv(sockFd, &serverBack, 1, 0);
            if(serverBack + '0' == '0'){
                puts("LOGIN");
            }
            else if(serverBack + '0' == '1'){
                puts("Wrong password.");
                exit(0);
            }
            else{
                puts("User doesn't exist.");
                exit(0);
            }
            int length;
            char token[100] = {0};
            recv(sockFd, &length, sizeof(int), 0);
            recv(sockFd, token, length, 0);
            write(fd, token, strlen(token));
            close(fd);
        }
    }

    //3.0部分分割线

    train_t t;
    while(1){
        bzero(&t, sizeof(train_t));
        int dataLength;
        char bashPre[1024] = {0};
        char line[1024] = {0};
        char responMsg[1024] = {0};
        // ret = recv(sockFd, buf, sizeof(buf), 0);
        // ERROR_CHECK(ret, -1, "recv xxx$");
        // puts(buf);
        // bzero(buf, sizeof(buf));
        recv(sockFd, &dataLength, sizeof(dataLength), 0);
        recv(sockFd, bashPre, dataLength, 0);
        printf("%s ", bashPre);//pwd$
        fflush(stdout);

        fgets(line, sizeof(line), stdin);
        char commandLine[200] = {0};
        strncpy(commandLine, line, strlen(line)-1);
        // puts(commandLine);
        strncpy(t.buf, line, strlen(line)-1);
        t.dataLength = strlen(t.buf);
        //printf("length = %d, line = %s\n", t.dataLength, t.buf);
        send(sockFd, &t, sizeof(dataLength)+t.dataLength, 0);//发送命令

        char command[1024] = {0};
        getCommand(commandLine, command);
        // printf("%s\n", command);

        if(strcmp(command, "cd") == 0){
            cd(sockFd);
        } 
        else if(strcmp(command, "ls") == 0 ){
            ls(sockFd);
        }
        else if(strcmp(command, "pwd") == 0){
            pwd(sockFd);
        }
        else if(strcmp(command, "rm") == 0){
            rm(sockFd);
        }
        else if(strcmp(command, "puts") == 0){
            //puts("if puts");
            upload(commandLine, sockFd);
        }
        else if(strcmp(command, "gets") == 0){
            recvFile(commandLine, sockFd);
        }
        else if(strcmp(command, "mkdir") == 0){
            makedir(sockFd);
        }
        else if(strcmp(command, "rmdir") == 0){
            removedir(sockFd);
        }
        else if(strcmp(command, "exit") == 0){

        }
        else{
            puts("Wrong Command!!");
        }
    }

}


// 根据用户的一整条命令buf 分析出命令的种类，存到command里
int getCommand(char buf[], char command[]){
    for(int i = 0; i < strlen(buf); ++i){
        if(buf[i] == ' ')
            break;
        command[i] = buf[i];
    }
}
